import Mn from 'backbone.marionette';

import { getOpt } from '../../tools.js';
import LoadingWidget from "../../widgets/LoadingWidget";
import DocumentViewerControlsView from "./DocumentViewerControlsView";

const template = require('./templates/BaseDocumentViewer.mustache');

/** Base for inlined file viewer
 *
 * Offers a document rendering area and a toolbar with zoom/paging options
 *
 * Subclass must implement/override :
 *
 * - zoom() method
 * - onRender() method or template var to customize rendering
 *
 * Subclass may override, if document format supports multipage:
 *
 * - isMultipage() method
 * - onPagePrevious() method
 * - onPageNext() method
 */
const BaseDocumentViewerView = Mn.View.extend({
    attributes: {class: 'preview'},
    ui: {
        document_container: '.document_container',
    },
    regions: {
        controls: '.controls',
        loader: ".loader",
    },
    template: template,
    childViewEvents: {
        'zoom:in': 'onZoomIn',
        'zoom:out': 'onZoomOut',
        'page:previous': 'onPagePrevious',
        'page:next': 'onPageNext',
        'open': 'onOpen',
        "loader:start": "showLoader",
        "loader:stop": "hideLoader",
    },
    initialize(options) {
        this.title = this.getOption('title');
        this.footerText = this.getOption('footerText');
        this.fileUrl = this.getOption('fileUrl');
        this.fileLabel = this.getOption('label');
        this.showControls = getOpt(this, 'showControls', true);
    },
    /** Helper method to compute x scroll after zoom
     *
     * Goal is to maintain constant viewport center by paning to computed position
     * after zoom. Has to be called *prior* to zooming.
     *
     * @param {Element} container the scrollable container element
     * @param {Number} ratio the zoom ratio we are going to apply
     */
    getXScroll(container, factor){
        return (container.scrollLeft + container.clientWidth/2) * factor - container.clientWidth/2;
    },
    /** Helper method to compute y scroll after zoom
     *
     * Goal is to maintain constant viewport center by paning to computed position
     * after zoom. Has to be called *prior* to zooming.
     *
     * @param {Element} container the scrollable container element
     * @param {Number} ratio the zoom ratio we are going to apply
     */
    getYScroll(container, factor){
        return (container.scrollTop + container.clientHeight/2) * factor - container.clientHeight/2;
    },
    onZoomIn(){this.zoom(1.5)},
    onZoomOut(){this.zoom(0.6666)},
    zoom(factor){},

    onOpen(){window.open(this.fileUrl)},

    onPagePrevious(){},
    onPageNext(){},  // To implement if multipage is required
    isMultipage(){return false}, // To implement if multipage is required

    onRender(){
        this.renderControls(this);
    },
    renderControls(this_){
        if(this.showControls) {
            let view = new DocumentViewerControlsView({
                multipage: this.isMultipage(),
            });
            this_.showChildView('controls', view);
        }
    },
    templateContext(){
        return {
            'title': this.title,
            'footerText': this.footerText,
        };
    },
    showLoader() {
        const view = new LoadingWidget();
        this.showChildView("loader", view);
    },
    hideLoader() {
        this.getRegion('loader').empty();
    },
});
export default BaseDocumentViewerView;
